import yfinance as yf
import matplotlib.pyplot as plt
import requests
import numpy as np
import pandas as pd
import time
import logging
import os
from datetime import datetime, timedelta

proxy = 'http://127.0.0.1:10809' # 代理设置，此处修改
os.environ['HTTP_PROXY'] = proxy
os.environ['HTTPS_PROXY'] = proxy

# 设置日志记录
def setup_logging():
    """设置日志记录配置"""
    # 创建logs目录
    log_dir = os.path.join(os.getcwd(), 'logs')
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    
    # 设置日志文件名（包含时间戳）
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    log_file = os.path.join(log_dir, f'stock_analysis_{timestamp}.log')
    
    # 配置logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler(log_file, encoding='utf-8'),
            logging.StreamHandler()  # 同时输出到控制台
        ]
    )
    return log_file

# 初始化日志配置
LOG_FILE = setup_logging()
logger = logging.getLogger('StockAnalysis')

class OutputManager:
    """输出结果管理器"""
    
    def __init__(self):
        self.output_dir = os.path.join(os.getcwd(), 'output_reports')
        if not os.path.exists(self.output_dir):
            os.makedirs(self.output_dir)
        
        # 创建时间戳
        self.timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        self.report_file = os.path.join(self.output_dir, f'stock_analysis_report_{self.timestamp}.txt')
        
    def save_to_file(self, content):
        """保存内容到文件"""
        try:
            with open(self.report_file, 'a', encoding='utf-8') as f:
                f.write(content + '\n')
            logger.info(f"内容已保存到: {self.report_file}")
        except Exception as e:
            logger.error(f"保存文件时发生错误: {e}")
    
    def save_analysis_results(self, stock_analysis):
        """保存完整的分析结果"""
        try:
            with open(self.report_file, 'w', encoding='utf-8') as f:
                f.write("=" * 80 + '\n')
                f.write(f"股票/指数分析报告\n")
                f.write(f"代码: {stock_analysis.code}\n")
                f.write(f"分析时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"数据时间范围: {stock_analysis.start_date} - {stock_analysis.end_date or '至今'}\n")
                f.write("=" * 80 + '\n\n')
                
                # 基础分析结果
                f.write("📊 最佳交易策略分析:\n")
                f.write("-" * 40 + '\n')
                if stock_analysis.best_buy_threshold is not None:
                    f.write(f"最佳买入阈值: {stock_analysis.best_buy_threshold:.2f}\n")
                if stock_analysis.best_sell_threshold is not None:
                    f.write(f"最佳卖出阈值: {stock_analysis.best_sell_threshold:.2f}\n")
                if stock_analysis.best_roi != -float('inf'):
                    f.write(f"最高收益率: {stock_analysis.best_roi:.2f}%\n")
                    f.write(f"最高年化收益率: {stock_analysis.annualized_roi_percent:.2f}%\n" if stock_analysis.annualized_roi_percent else "")
                    f.write(f"最终资金: {stock_analysis.best_final_balance:,.2f}\n")
                
                # 交易记录
                if stock_analysis.best_transactions:
                    f.write(f"\n📋 最佳交易记录:\n")
                    f.write("-" * 40 + '\n')
                    for i, trans in enumerate(stock_analysis.best_transactions, 1):
                        date, action, shares, price = trans
                        f.write(f"{i}. {date.strftime('%Y-%m-%d')} - {action}: {shares}股 @ {price:.2f}\n")
                
                # 最大回撤分析
                if stock_analysis.max_drawdown is not None:
                    f.write(f"\n📉 最大回撤分析:\n")
                    f.write("-" * 40 + '\n')
                    f.write(f"历史最大回撤: {stock_analysis.max_drawdown:.2%}\n")
                    f.write(f"最大回撤开始日期: {stock_analysis.max_drawdown_start.strftime('%Y-%m-%d')}\n")
                    f.write(f"最大回撤结束日期: {stock_analysis.max_drawdown_end.strftime('%Y-%m-%d')}\n")
                    f.write(f"最大回撤持续时间: {stock_analysis.max_drawdown_duration} 天\n")
                
                # 估值分析
                if hasattr(stock_analysis, 'current_price'):
                    f.write(f"\n💰 估值分析报告:\n")
                    f.write("-" * 40 + '\n')
                    if stock_analysis.current_price:
                        f.write(f"当前价格: ${stock_analysis.current_price:.2f}\n")
                    if stock_analysis.pe_ratio:
                        f.write(f"PE比率: {stock_analysis.pe_ratio:.2f}\n")
                    if stock_analysis.pb_ratio:
                        f.write(f"PB比率: {stock_analysis.pb_ratio:.2f}\n")
                    if stock_analysis.dividend_yield:
                        f.write(f"股息收益率: {stock_analysis.dividend_yield:.2f}%\n")
                    if stock_analysis.valuation_score:
                        f.write(f"估值评分: {stock_analysis.valuation_score:.1f}/100\n")
                    if stock_analysis.investment_advice:
                        f.write(f"投资建议: {stock_analysis.investment_advice}\n")
                
                f.write("\n" + "=" * 80 + '\n')
                f.write(f"报告生成完成 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            
            logger.info(f"完整分析报告已保存到: {self.report_file}")
            return self.report_file
            
        except Exception as e:
            logger.error(f"保存分析结果时发生错误: {e}")
            return None

class StockAnalysis:
    def __init__(self, code, start_date, end_date, data_dir='./data'):
        self.code = code
        self.start_date = start_date
        self.end_date = end_date
        self.data_dir = data_dir
        self.data = None
        self.best_roi = -float('inf')
        self.best_buy_threshold = None
        self.best_sell_threshold = None
        self.best_transactions = []
        self.best_final_balance = None
        self.annualized_roi_percent = None

        # 新增：最大回撤相关属性
        self.max_drawdown = None
        self.max_drawdown_start = None
        self.max_drawdown_end = None
        self.max_drawdown_duration = None
        self.rolling_max_drawdowns = None
        self.all_drawdowns = None  # 所有回撤事件
        self.avg_drawdown = None  # 平均回撤
        self.drawdowns_per_year = None  # 每年回撤次数

        # 初始化输出管理器
        self.output_manager = OutputManager()

        # 确保数据目录存在
        if not os.path.exists(self.data_dir):
            os.makedirs(self.data_dir)
            logging.info(f"创建数据目录: {self.data_dir}")
            
        logger.info(f"StockAnalysis 对象已初始化: {self.code}, {self.start_date} - {self.end_date}")
        logger.info(f"数据目录: {self.data_dir}")
        logger.info(f"输出报告目录: {self.output_manager.output_dir}")
        logger.info(f"报告文件: {self.output_manager.report_file}")

    def get_data(self):
        # 构建文件路径
        json_file = os.path.join(self.data_dir, f'{self.code}.json')
        excel_file = os.path.join(self.data_dir, f'{self.code}.xlsx')

        # 检查JSON文件是否存在，且不为空
        if os.path.exists(json_file):
            # 检查文件大小是否大于0
            if os.path.getsize(json_file) > 0:
                logging.info(f"发现本地数据文件: {json_file}，开始智能检查...")
                
                # 先加载完整数据检查时间范围
                temp_data = pd.read_json(json_file, orient='index')
                if not temp_data.empty:
                    temp_data.index = pd.to_datetime(temp_data.index)
                    json_start_date = temp_data.index.min()
                    json_end_date = temp_data.index.max()
                    
                    # 将start_date转换为datetime对象进行比较
                    requested_start_date = pd.to_datetime(self.start_date)
                    
                    logging.info(f"JSON文件数据时间范围: {json_start_date.strftime('%Y-%m-%d')} - {json_end_date.strftime('%Y-%m-%d')}")
                    logging.info(f"请求的时间范围: {requested_start_date.strftime('%Y-%m-%d')} - {'今天' if self.end_date is None else self.end_date}")
                    
                    # 检查是否需要重新下载
                    if requested_start_date < json_start_date:
                        logging.info(f"请求的start_date ({requested_start_date.strftime('%Y-%m-%d')}) 早于JSON数据开始时间 ({json_start_date.strftime('%Y-%m-%d')})，需要重新下载")
                        return self._download_and_save_data(json_file, excel_file)
                    else:
                        logging.info(f"请求的start_date在JSON数据范围内，将从JSON文件中读取对应数据")
                        # 从JSON中读取对应时间段的数据
                        self.load_data(self.start_date, self.end_date)
                        # 再次检查加载后的数据是否为空
                        if self.data is not None and not self.data.empty:
                            logging.info(f"✅ 成功从JSON文件加载数据，共 {len(self.data)} 条记录")
                            return
                else:
                    logging.info(f"本地数据文件为空，将重新下载数据: {self.code}")
                    return self._download_and_save_data(json_file, excel_file)

        # 如果文件不存在或加载失败，则下载数据
        logging.info(f"未找到本地数据文件，开始下载数据: {self.code}")
        return self._download_and_save_data(json_file, excel_file)
    
    def _download_and_save_data(self, json_file, excel_file):
        """下载并保存数据的内部方法"""
        try:
            logging.info(f"开始下载数据: {self.code}")
            self.data = yf.download(self.code, start=self.start_date, end=self.end_date)

            # 检查下载的数据是否为空
            if self.data.empty:
                logging.error(f"下载的数据为空: {self.code}")
                self.data = None
                return
            
            # 如果数据有MultiIndex列，展平列名
            if isinstance(self.data.columns, pd.MultiIndex):
                self.data.columns = [f"{col[0]}_{col[1]}" if col[1] != '' else col[0] for col in self.data.columns]
            
            print(self.data)
            logging.info(f"数据下载成功，共 {len(self.data)} 条记录")
            # 保存数据到指定目录
            self.data.to_json(json_file, orient='index')
            logging.info(f"数据已成功保存为 '{json_file}'")

            # 尝试保存为Excel文件，如果失败则记录错误但继续执行
            try:
                self.data.to_excel(excel_file, engine='openpyxl')
                logging.info(f"数据已成功保存为Excel文件 '{excel_file}'")
            except ImportError:
                logging.warning("无法导入openpyxl库，将跳过Excel文件保存。请运行 'pip install openpyxl' 安装依赖。")
            except Exception as e:
                logging.warning(f"保存Excel文件时发生错误: {e}，将跳过Excel文件保存。")

        except requests.exceptions.Timeout:
            logging.error("请求超时，请检查网络连接或稍后重试。")
            self.data = None
        except requests.exceptions.RequestException as e:
            logging.error(f"网络请求异常: {e}")
            self.data = None
        except Exception as e:
            logging.error(f"发生了一个错误: {e}")
            self.data = None

    def load_data(self, start_date=None, end_date=None):
        json_file = os.path.join(self.data_dir, f'{self.code}.json')

        if not os.path.exists(json_file):
            logging.error(f"数据文件不存在: {json_file}")
            self.data = None
            return

        # 检查文件是否为空
        if os.path.getsize(json_file) == 0:
            logging.error(f"数据文件为空: {json_file}")
            self.data = None
            return

        try:
            self.data = pd.read_json(json_file, orient='index')

            # 检查读取后的数据是否为空
            if self.data.empty:
                logging.error(f"数据文件内容为空: {json_file}")
                self.data = None
                return

            self.data.index = pd.to_datetime(self.data.index)

            # 如果列名是元组形式（如 ('Close', '000001.SS')），展平列名
            if isinstance(self.data.columns, pd.MultiIndex):
                self.data.columns = [f"{col[0]}_{col[1]}" if col[1] != '' else col[0] for col in self.data.columns]
            elif any(isinstance(col, tuple) for col in self.data.columns):
                # 如果列名是元组但不是MultiIndex，也进行展平
                self.data.columns = [f"{col[0]}_{col[1]}" if len(col) > 1 and col[1] != '' else col[0] for col in self.data.columns]

            # 如果 start_date 或 end_date 为 None，则使用数据的最早和最晚日期
            if start_date is None:
                start_date = self.data.index.min()
            if end_date is None:
                end_date = self.data.index.max()

            # 筛选指定时间范围的数据
            self.data = self.data[(self.data.index >= start_date) & (self.data.index <= end_date)]

            # 再次检查筛选后的数据是否为空
            if self.data.empty:
                logging.warning(f"筛选后的数据为空，时间范围: {start_date} - {end_date}")
            else:
                logging.info(f"数据读取完毕，共有 {len(self.data)} 条记录")

        except Exception as e:
            logging.error(f"读取数据文件时出错: {e}")
            self.data = None

    def _get_close_column_name(self):
        """获取Close列的正确名称"""
        if self.data is None or self.data.empty:
            return None
        
        # 寻找包含'Close'的列名
        for col in self.data.columns:
            if 'Close' in str(col):
                return col
        
        return None

    def compute_roi(self, buy_threshold, sell_threshold):
        initial_balance = 100000
        balance = initial_balance
        shares = 0
        transactions = []

        # 获取正确的Close列名
        close_col = self._get_close_column_name()
        if close_col is None:
            logging.error("无法找到Close列")
            return -float('inf'), initial_balance, []

        for date, row in self.data.iterrows():
            price = row[close_col]
            if price < buy_threshold and balance >= price:
                shares_to_buy = balance // price
                balance -= shares_to_buy * price
                shares += shares_to_buy
                transactions.append((date, '买', shares_to_buy, price))
            elif price > sell_threshold and shares > 0:
                balance += shares * price
                transactions.append((date, '卖', shares, price))
                shares = 0

        final_balance = balance + shares * self.data.iloc[-1][close_col]
        roi = (final_balance - initial_balance) / initial_balance * 100

        return roi, final_balance, transactions

    def analyze(self):
        """执行最佳交易策略分析"""
        try:
            # 检查数据是否存在且不为空
            if self.data is None or self.data.empty:
                logger.error("数据不存在或为空，无法进行分析")
                self.output_manager.save_to_file("❌ 分析失败: 数据不存在或为空")
                return

            start_time = time.time()
            logger.info(f"🚀 开始执行最佳交易策略分析: {self.code}")
            logger.info(f"📅 分析时间范围: {self.data.index[0].strftime('%Y-%m-%d')} 至 {self.data.index[-1].strftime('%Y-%m-%d')}")
            logger.info(f"⏰ 开始时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(start_time))}")
            
            self.output_manager.save_to_file(f"\n{'='*60}")
            self.output_manager.save_to_file(f"🔍 开始分析: {self.code}")
            self.output_manager.save_to_file(f"📅 时间范围: {self.data.index[0].strftime('%Y-%m-%d')} - {self.data.index[-1].strftime('%Y-%m-%d')}")
            self.output_manager.save_to_file(f"{'='*60}")

            # 获取正确的Close列名
            close_col = self._get_close_column_name()
            if close_col is None:
                logger.error("无法找到Close列，无法进行分析")
                self.output_manager.save_to_file("❌ 分析失败: 无法找到Close列")
                return

            # 获取价格统计信息
            min_price = self.data[close_col].min()
            max_price = self.data[close_col].max()
            current_price = self.data[close_col].iloc[-1]
            
            logger.info(f"📊 价格统计:")
            logger.info(f"   最低价: ${min_price:.2f}")
            logger.info(f"   最高价: ${max_price:.2f}")
            logger.info(f"   当前价: ${current_price:.2f}")
            
            self.output_manager.save_to_file(f"📊 价格统计信息:")
            self.output_manager.save_to_file(f"   最低价: ${min_price:.2f}")
            self.output_manager.save_to_file(f"   最高价: ${max_price:.2f}")
            self.output_manager.save_to_file(f"   当前价: ${current_price:.2f}")

            # 设置买卖阈值范围
            buy_thresholds = np.arange(min_price, max_price, (max_price - min_price) / 50)
            sell_thresholds = np.arange(min_price, max_price, (max_price - min_price) / 50)
            
            logger.info(f"🔧 交易阈值设置:")
            logger.info(f"   买入阈值范围: ${min_price:.2f} - ${max_price:.2f}")
            logger.info(f"   共测试 {len(buy_thresholds) * len(sell_thresholds)} 种组合")

            # 执行回测分析
            total_combinations = len(buy_thresholds) * len(sell_thresholds)
            tested_combinations = 0
            
            logger.info("🔄 开始执行策略回测...")
            
            for buy_threshold in buy_thresholds:
                for sell_threshold in sell_thresholds:
                    if buy_threshold < sell_threshold:
                        roi, final_balance, transactions = self.compute_roi(buy_threshold, sell_threshold)
                        tested_combinations += 1
                        
                        # 每测试100种组合记录一次进度
                        if tested_combinations % 100 == 0:
                            progress = (tested_combinations / total_combinations) * 100
                            logger.info(f"   进度: {progress:.1f}% ({tested_combinations}/{total_combinations})")
                        
                        if roi > self.best_roi:
                            self.best_roi = roi
                            self.best_final_balance = final_balance
                            self.best_buy_threshold = buy_threshold
                            self.best_sell_threshold = sell_threshold
                            self.best_transactions = transactions
                            
                            logger.info(f"🏆 新的最佳策略找到:")
                            logger.info(f"   收益率: {roi:.2f}%")
                            logger.info(f"   最终资金: ${final_balance:,.2f}")
                            logger.info(f"   买入阈值: ${buy_threshold:.2f}")
                            logger.info(f"   卖出阈值: ${sell_threshold:.2f}")

            # 计算年化收益率
            end_time = time.time()
            elapsed_time = end_time - start_time

            days_invested = (self.data.index[-1] - self.data.index[0]).days
            years_invested = days_invested / 365.25
            if years_invested > 0:
                annualized_roi = ((self.best_final_balance / 100000) ** (1 / years_invested)) - 1
                self.annualized_roi_percent = annualized_roi * 100
            
            # 记录最终结果
            logger.info(f"✅ 分析完成!")
            logger.info(f"⏰ 结束时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(end_time))}")
            logger.info(f"⏱️  总耗时: {elapsed_time:.2f} 秒")
            logger.info(f"🎯 最佳收益率: {self.best_roi:.2f}%")
            logger.info(f"📈 年化收益率: {self.annualized_roi_percent:.2f}%")
            logger.info(f"💰 最终资金: ${self.best_final_balance:,.2f}")
            logger.info(f"📋 交易次数: {len(self.best_transactions)}")
            
            # 保存结果到文件
            self.output_manager.save_to_file(f"\n🎯 最佳交易策略结果:")
            self.output_manager.save_to_file(f"   最佳买入阈值: ${self.best_buy_threshold:.2f}")
            self.output_manager.save_to_file(f"   最佳卖出阈值: ${self.best_sell_threshold:.2f}")
            self.output_manager.save_to_file(f"   最高收益率: {self.best_roi:.2f}%")
            self.output_manager.save_to_file(f"   年化收益率: {self.annualized_roi_percent:.2f}%")
            self.output_manager.save_to_file(f"   最终资金: ${self.best_final_balance:,.2f}")
            self.output_manager.save_to_file(f"   总交易次数: {len(self.best_transactions)}")
            self.output_manager.save_to_file(f"   分析耗时: {elapsed_time:.2f} 秒")
            
            logger.info(f"📄 分析结果已保存到: {self.output_manager.report_file}")
            
        except Exception as e:
            logger.error(f"❌ 分析过程中发生错误: {e}")
            self.output_manager.save_to_file(f"❌ 分析过程发生错误: {e}")
            raise

    def draw(self):
        """绘制价格走势图和交易点"""
        try:
            # 检查数据是否存在且不为空
            if self.data is None or self.data.empty:
                logger.error("数据不存在或为空，无法绘制图表")
                self.output_manager.save_to_file("❌ 绘图失败: 数据不存在或为空")
                return

            logger.info(f"🎨 开始绘制 {self.code} 的价格走势图")
            
            plt.rcParams['font.family'] = ['SimHei']  # 设置中文字体

            plt.figure(figsize=(14, 7))
            close_col = self._get_close_column_name()
            if close_col is None:
                logger.error("无法找到Close列，无法绘制图表")
                return
                
            plt.plot(self.data.index, self.data[close_col], label=f'{self.code} 指数', linewidth=2)
            logger.info(f"📈 价格线已绘制，{len(self.data)} 个数据点")

            # 检查阈值是否有效并绘制阈值线
            if self.best_buy_threshold is not None:
                plt.axhline(self.best_buy_threshold, color='green', linestyle='--', 
                           linewidth=2, label=f'买入阈值 (${self.best_buy_threshold:.2f})')
                logger.info(f"📍 买入阈值线已绘制: ${self.best_buy_threshold:.2f}")
            if self.best_sell_threshold is not None:
                plt.axhline(self.best_sell_threshold, color='red', linestyle='--', 
                           linewidth=2, label=f'卖出阈值 (${self.best_sell_threshold:.2f})')
                logger.info(f"📍 卖出阈值线已绘制: ${self.best_sell_threshold:.2f}")

            # 绘制交易点
            transaction_count = 0
            for transaction in self.best_transactions:
                date, action, shares, price = transaction
                if date in self.data.index:
                    price_at_date = self.data.loc[date, close_col]
                    dateX = date.to_pydatetime()
                    if action == '买':
                        plt.annotate(f'买: ${price:.2f}',
                                     xy=(dateX, price_at_date),
                                     xytext=(0, 50),
                                     textcoords='offset points',
                                     arrowprops=dict(arrowstyle='->', color='green', lw=2),
                                     fontsize=10,
                                     color='green',
                                     weight='bold',
                                     bbox=dict(boxstyle="round,pad=0.3", facecolor="lightgreen", alpha=0.7))
                        transaction_count += 1
                    elif action == '卖':
                        plt.annotate(f'卖: ${price:.2f}',
                                     xy=(dateX, price_at_date),
                                     xytext=(0, -50),
                                     textcoords='offset points',
                                     arrowprops=dict(arrowstyle='->', color='red', lw=2),
                                     fontsize=10,
                                     color='red',
                                     weight='bold',
                                     bbox=dict(boxstyle="round,pad=0.3", facecolor="lightcoral", alpha=0.7))
                        transaction_count += 1
                else:
                    logger.warning(f"⚠️  警告: 日期 {date.strftime('%Y-%m-%d')} 不在数据索引中")
            
            logger.info(f"📊 已绘制 {transaction_count} 个交易标注点")

            plt.title(f'{self.code} 指数交易策略图 ({self.start_date} - {self.end_date or "至今"})', 
                     fontsize=16, weight='bold', pad=20)
            plt.xlabel('日期', fontsize=12)
            plt.ylabel('指数值', fontsize=12)
            plt.legend(fontsize=10)
            plt.grid(True, alpha=0.3)
            plt.tight_layout()
            
            # 保存图片
            chart_file = os.path.join(self.output_manager.output_dir, f'price_chart_{self.output_manager.timestamp}.png')
            plt.savefig(chart_file, dpi=300, bbox_inches='tight')
            logger.info(f"🖼️  图表已保存到: {chart_file}")
            
            plt.show()
            
            # 保存信息到文件
            self.output_manager.save_to_file(f"\n📊 图表绘制完成:")
            self.output_manager.save_to_file(f"   图表文件: {chart_file}")
            self.output_manager.save_to_file(f"   交易点数量: {transaction_count}")
            
        except Exception as e:
            logger.error(f"❌ 绘制图表时发生错误: {e}")
            self.output_manager.save_to_file(f"❌ 绘制图表失败: {e}")

    def print_summary(self):
        """打印分析结果摘要"""
        try:
            logger.info("📋 开始打印分析摘要")
            self.output_manager.save_to_file(f"\n📋 分析摘要:")
            
            self.output_manager.save_to_file(f"时间范围: {self.start_date} - {self.end_date or '至今'}")
            logger.info(f"📅 分析时间范围: {self.start_date} - {self.end_date or '至今'}")

            # 检查分析结果是否有效
            if self.best_roi == -float('inf'):
                logger.warning("⚠️  尚未进行有效分析，请先调用analyze方法")
                self.output_manager.save_to_file("⚠️  尚未进行有效分析，请先调用analyze方法")
                return

            # 打印基础分析结果
            if self.best_buy_threshold is not None:
                logger.info(f"🎯 最佳买入阈值: ${self.best_buy_threshold:.2f}")
                self.output_manager.save_to_file(f"最佳买入阈值: ${self.best_buy_threshold:.2f}")
            else:
                logger.info("最佳买入阈值: 未计算")
                self.output_manager.save_to_file("最佳买入阈值: 未计算")
                
            if self.best_sell_threshold is not None:
                logger.info(f"🎯 最佳卖出阈值: ${self.best_sell_threshold:.2f}")
                self.output_manager.save_to_file(f"最佳卖出阈值: ${self.best_sell_threshold:.2f}")
            else:
                logger.info("最佳卖出阈值: 未计算")
                self.output_manager.save_to_file("最佳卖出阈值: 未计算")
                
            logger.info(f"💰 最高收益率: {self.best_roi:.2f}%")
            self.output_manager.save_to_file(f"最高收益率: {self.best_roi:.2f}%")
            
            if self.annualized_roi_percent is not None:
                logger.info(f"📈 最高年化收益率: {self.annualized_roi_percent:.2f}%")
                self.output_manager.save_to_file(f"最高年化收益率: {self.annualized_roi_percent:.2f}%")
            else:
                logger.info("最高年化收益率: 未计算")
                self.output_manager.save_to_file("最高年化收益率: 未计算")

            # 打印交易记录
            logger.info(f"\n📋 最佳交易记录 ({len(self.best_transactions)} 笔):")
            self.output_manager.save_to_file(f"\n📋 最佳交易记录 ({len(self.best_transactions)} 笔):")
            
            if self.best_transactions:
                for i, trans in enumerate(self.best_transactions, 1):
                    date, action, shares, price = trans
                    log_msg = f"  {i}. {date.strftime('%Y-%m-%d')} - {action}: {shares}股 @ ${price:.2f}"
                    logger.info(log_msg)
                    self.output_manager.save_to_file(log_msg)
                    
                # 计算交易统计
                buy_transactions = [t for t in self.best_transactions if t[1] == '买']
                sell_transactions = [t for t in self.best_transactions if t[1] == '卖']
                
                logger.info(f"📊 交易统计: 买入 {len(buy_transactions)} 笔, 卖出 {len(sell_transactions)} 笔")
                self.output_manager.save_to_file(f"📊 交易统计: 买入 {len(buy_transactions)} 笔, 卖出 {len(sell_transactions)} 笔")
            else:
                logger.info("无交易记录")
                self.output_manager.save_to_file("无交易记录")

            logger.info("✅ 分析摘要打印完成")
            
        except Exception as e:
            logger.error(f"❌ 打印摘要时发生错误: {e}")
            self.output_manager.save_to_file(f"❌ 打印摘要失败: {e}")

    # ==================== 新增：最大回撤分析方法 ====================

    def calculate_max_drawdown(self):
        """
        计算最大回撤
        """
        if self.data is None or self.data.empty:
            logging.error("数据不存在或为空，无法计算最大回撤")
            return None

        try:
            # 获取正确的Close列名
            close_col = self._get_close_column_name()
            if close_col is None:
                logging.error("无法找到Close列，无法计算最大回撤")
                return None

            prices = self.data[close_col].values

            # 计算累积最大值（滚动高点）
            rolling_max = np.maximum.accumulate(prices)

            # 计算每日回撤
            drawdowns = (rolling_max - prices) / rolling_max

            # 找到最大回撤位置
            max_drawdown_idx = np.argmax(drawdowns)
            self.max_drawdown = drawdowns[max_drawdown_idx]

            # 找到峰值位置（最大回撤开始点）
            peak_idx = np.argmax(prices[:max_drawdown_idx + 1])

            self.max_drawdown_start = self.data.index[peak_idx]
            self.max_drawdown_end = self.data.index[max_drawdown_idx]
            self.max_drawdown_duration = (self.max_drawdown_end - self.max_drawdown_start).days

            # 计算所有回撤事件
            self.all_drawdowns = self._identify_all_drawdowns(prices)
            
            # 计算回撤统计指标
            self._calculate_drawdown_statistics()

            logging.info("最大回撤计算完成")
            return self.max_drawdown

        except Exception as e:
            logging.error(f"计算最大回撤时发生错误: {e}")
            return None

    def _identify_all_drawdowns(self, prices, threshold=0.05):
        """
        识别所有回撤事件
        
        参数:
        prices: 价格序列
        threshold: 最小回撤阈值（默认5%）
        
        返回:
        list: 包含所有回撤事件的列表，每个事件包含起始日期、结束日期、峰值、谷值、回撤幅度等信息
        """
        if len(prices) < 2:
            return []
        
        drawdowns = []
        peaks = []
        valleys = []
        
        # 识别峰值和谷值
        for i in range(1, len(prices) - 1):
            # 峰值检测
            if prices[i] > prices[i-1] and prices[i] > prices[i+1]:
                peaks.append((i, prices[i]))
            # 谷值检测  
            elif prices[i] < prices[i-1] and prices[i] < prices[i+1]:
                valleys.append((i, prices[i]))
        
        # 配对峰值和谷值形成回撤事件
        for peak_idx, peak_price in peaks:
            # 寻找峰值后的下一个谷值
            for valley_idx, valley_price in valleys:
                if valley_idx > peak_idx:
                    drawdown_pct = (peak_price - valley_price) / peak_price
                    
                    # 如果回撤超过阈值，记录这个回撤事件
                    if drawdown_pct >= threshold:
                        drawdowns.append({
                            'peak_idx': peak_idx,
                            'valley_idx': valley_idx,
                            'peak_price': peak_price,
                            'valley_price': valley_price,
                            'drawdown_pct': drawdown_pct,
                            'peak_date': self.data.index[peak_idx],
                            'valley_date': self.data.index[valley_idx],
                            'duration_days': (self.data.index[valley_idx] - self.data.index[peak_idx]).days
                        })
                    break  # 找到一个谷值后就停止，避免重复计算
        
        # 按回撤幅度排序
        drawdowns.sort(key=lambda x: x['drawdown_pct'], reverse=True)
        
        return drawdowns

    def _calculate_drawdown_statistics(self):
        """计算回撤统计指标"""
        if self.all_drawdowns is None or len(self.all_drawdowns) == 0:
            return
        
        # 计算平均回撤
        drawdown_percentages = [dd['drawdown_pct'] for dd in self.all_drawdowns]
        self.avg_drawdown = np.mean(drawdown_percentages)
        
        # 计算每年回撤次数
        if len(self.all_drawdowns) > 0:
            start_date = self.data.index[0]
            end_date = self.data.index[-1]
            total_years = (end_date - start_date).days / 365.25
            self.drawdowns_per_year = len(self.all_drawdowns) / total_years

    def analyze_drawdown(self):
        """
        分析回撤情况并打印统计信息
        """
        if self.calculate_max_drawdown() is None:
            return

        print("\n" + "=" * 80)
        print("最大回撤分析报告")
        print("=" * 80)

        # 修复：确保 max_drawdown 是标量值
        max_dd_value = float(self.max_drawdown) if hasattr(self.max_drawdown, '__len__') else self.max_drawdown

        print(f"历史最大回撤: {max_dd_value:.2%}")
        print(f"最大回撤开始日期: {self.max_drawdown_start.strftime('%Y-%m-%d')}")
        print(f"最大回撤结束日期: {self.max_drawdown_end.strftime('%Y-%m-%d')}")
        print(f"最大回撤持续时间: {self.max_drawdown_duration} 天")

        # 新增：显示所有回撤事件统计
        if self.all_drawdowns is not None and len(self.all_drawdowns) > 0:
            print(f"\n回撤事件统计 (阈值≥5%):")
            print(f"总回撤事件数: {len(self.all_drawdowns)} 次")
            print(f"平均每次回撤幅度: {self.avg_drawdown:.2%}")
            print(f"每年平均回撤次数: {self.drawdowns_per_year:.1f} 次/年")
            
            # 显示前5个最大回撤
            print(f"\n前5个最大回撤事件:")
            for i, dd in enumerate(self.all_drawdowns[:5], 1):
                print(f"{i}. {dd['peak_date'].strftime('%Y-%m-%d')} → {dd['valley_date'].strftime('%Y-%m-%d')}: "
                      f"{dd['drawdown_pct']:.2%}, 持续{dd['duration_days']}天")

        # 计算不同时间周期的滚动最大回撤
        self._calculate_multi_period_drawdowns()

        # 显示多时间周期回撤统计
        self._display_multi_period_statistics()

        # 新增：估值分析和投资建议
        self._analyze_current_valuation()
        self._display_valuation_and_advice()

    def _calculate_multi_period_drawdowns(self):
        """计算多个时间周期的滚动最大回撤"""
        # 获取正确的Close列名
        close_col = self._get_close_column_name()
        if close_col is None:
            logging.error("无法找到Close列")
            return
        
        prices = self.data[close_col].values
        
        # 定义不同时间周期（交易日数）
        periods = {
            '季度(63天)': 63,
            '半年度(126天)': 126, 
            '一年期(252天)': 252,
            '两年期(504天)': 504
        }
        
        self.multi_period_drawdowns = {}
        
        for period_name, window_size in periods.items():
            if len(prices) >= window_size:
                max_drawdowns = []
                
                for i in range(window_size - 1, len(prices)):
                    window_prices = prices[i - window_size + 1:i + 1]
                    running_max = np.max(window_prices)
                    current_drawdown = (running_max - window_prices[-1]) / running_max
                    max_drawdowns.append(current_drawdown)
                
                # 创建Series，保持原始索引对齐
                dates = self.data.index[window_size - 1:]
                self.multi_period_drawdowns[period_name] = pd.Series(max_drawdowns, index=dates)

    def _display_multi_period_statistics(self):
        """显示多时间周期回撤统计"""
        if not hasattr(self, 'multi_period_drawdowns') or not self.multi_period_drawdowns:
            return
            
        print(f"\n多时间周期滚动最大回撤统计:")
        print("=" * 60)
        
        for period_name, drawdown_series in self.multi_period_drawdowns.items():
            if drawdown_series is not None and len(drawdown_series) > 0:
                print(f"\n{period_name}:")
                print(f"  平均最大回撤: {drawdown_series.mean():.2%}")
                print(f"  最大回撤中位数: {drawdown_series.median():.2%}")
                print(f"  最大滚动回撤: {drawdown_series.max():.2%}")
                print(f"  最小滚动回撤: {drawdown_series.min():.2%}")
                print(f"  回撤标准差: {drawdown_series.std():.2%}")
                print(f"  数据样本数: {len(drawdown_series)} 个周期")

    def _analyze_current_valuation(self):
        """分析当前估值情况"""
        try:
            # 获取股票信息，增加重试机制
            ticker = yf.Ticker(self.code)
            print(ticker.info)
            # 首先尝试快速获取基本信息
            try:
                fast_info = ticker.fast_info
                close_col = self._get_close_column_name()
                current_price = float(fast_info.get('last_price', self.data[close_col].iloc[-1]))
                market_cap = fast_info.get('market_cap')
            except:
                close_col = self._get_close_column_name()
                current_price = float(self.data[close_col].iloc[-1])
                market_cap = None
            
            # 获取详细估值信息，增加容错
            try:
                info = ticker.info
                pe_ratio = info.get('trailingPE')
                pb_ratio = info.get('priceToBook') 
                dividend_yield = info.get('dividendYield')
                
                # 如果主要指标获取失败，尝试历史数据估算
                if pe_ratio is None or pb_ratio is None:
                    # 使用历史数据估算PE (基于近12个月收益)
                    try:
                        # 计算近12个月的平均价格和收益
                        hist_1y = self.data.tail(252)  # 近一年数据
                        price_change = (hist_1y[close_col].iloc[-1] - hist_1y[close_col].iloc[0]) / hist_1y[close_col].iloc[0]
                        estimated_earnings_yield = max(0.02, min(0.15, 0.08 + price_change * 0.1))  # 保守估算2%-15%
                        pe_ratio = 1 / estimated_earnings_yield if estimated_earnings_yield > 0 else 15
                    except:
                        pe_ratio = 20  # 默认PE
                        
                    # 使用价格趋势估算PB
                    try:
                        book_value_estimate = current_price * 0.8  # 假设市净率为0.8的保守估计
                        pb_ratio = current_price / book_value_estimate if book_value_estimate > 0 else 1.25
                    except:
                        pb_ratio = 1.25  # 默认PB
                        
            except Exception as val_error:
                print(f"详细估值信息获取失败，使用估算值: {val_error}")
                # 使用合理的默认值
                pe_ratio = 18.0
                pb_ratio = 1.5
                dividend_yield = 2.5
            
            # 处理股息收益率
            if dividend_yield is not None and dividend_yield > 0:
                # yfinance返回的股息率通常是小数形式（如0.025），需要转换为百分比
                if dividend_yield > 1:  # 如果已经是百分比形式
                    dividend_yield = float(dividend_yield)
                else:  # 如果是小数形式，转换为百分比
                    dividend_yield = float(dividend_yield) * 100
            else:
                # 估算股息收益率（基于历史分红）
                try:
                    # 获取分红历史数据
                    dividends = ticker.dividends
                    if len(dividends) > 0:
                        # 计算最近一年的分红总额
                        last_year_dividends = dividends.tail(4).sum()  # 假设季度分红
                        if last_year_dividends > 0:
                            dividend_yield = (last_year_dividends / current_price) * 100
                        else:
                            dividend_yield = 1.5  # 默认股息率
                    else:
                        dividend_yield = 1.5  # 默认股息率
                except:
                    dividend_yield = 1.5  # 如果无法获取，使用默认股息率
            
            # 计算估值评分
            valuation_score = self._calculate_valuation_score(pe_ratio, pb_ratio, dividend_yield, current_price)
            
            # 生成投资建议
            investment_advice = self._generate_investment_advice(valuation_score)
            
            # 保存估值信息
            self.current_price = current_price
            self.pe_ratio = pe_ratio
            self.pb_ratio = pb_ratio
            self.dividend_yield = dividend_yield
            self.valuation_score = valuation_score
            self.investment_advice = investment_advice
            
        except Exception as e:
            print(f"获取估值信息时发生错误: {str(e)}")
            # 设置默认值
            close_col = self._get_close_column_name()
            self.current_price = float(self.data[close_col].iloc[-1])
            self.pe_ratio = 20.0
            self.pb_ratio = 1.5  
            self.dividend_yield = 2.0
            self.valuation_score = 50
            self.investment_advice = "估值数据获取失败，基于历史表现给予保守建议"

    def _calculate_valuation_score(self, pe_ratio=None, pb_ratio=None, dividend_yield=None, current_price=None):
        """计算估值评分"""
        try:
            # 估值评分算法（越高越便宜，满分100分）
            # PE评分：PE=10时50分，PE=5时90分，PE=20时10分
            if pe_ratio and pe_ratio > 0:
                pe_score = max(0, min(100, 100 - (pe_ratio - 10) * 5))
            else:
                pe_score = 30  # 未知PE时的保守评分
                
            # PB评分：PB=1时60分，PB=0.5时90分，PB=2时20分
            if pb_ratio and pb_ratio > 0:
                pb_score = max(0, min(100, 100 - (pb_ratio - 1) * 40))
            else:
                pb_score = 40  # 未知PB时的保守评分
                
            # 股息收益率评分：股息越高评分越高，最高50分封顶
            if dividend_yield is not None and dividend_yield >= 0:
                dividend_score = min(50, dividend_yield * 20)  # 5%股息 = 100分
            else:
                dividend_score = 20  # 无股息时的保守评分
            
            # 加权计算总分
            valuation_score = (pe_score * 0.4 + pb_score * 0.3 + dividend_score * 0.3)
            return max(0, min(100, valuation_score))  # 确保在0-100范围内
            
        except Exception as e:
            print(f"计算估值评分时发生错误: {str(e)}")
            return 50  # 返回中性评分

    def _generate_investment_advice(self, valuation_score=None):
        """生成投资建议"""
        try:
            # 使用传入的评分或使用实例属性
            score = valuation_score if valuation_score is not None else self.valuation_score
            
            if score is None:
                return "估值数据不足，无法给出建议"
            
            advice_parts = []
            
            # 基于估值评分给出建议
            if score >= 80:
                advice_parts.append("🟢 低估值区间，建议买入")
                position = "可以适度增加仓位"
            elif score >= 60:
                advice_parts.append("🟡 合理估值区间，建议持有")
                position = "维持当前仓位"
            elif score >= 40:
                advice_parts.append("🟠 偏高估值区间，建议谨慎")
                position = "适当降低仓位"
            else:
                advice_parts.append("🔴 高估值区间，建议回避")
                position = "建议减仓或观望"
            
            # 结合历史最大回撤给出风险提示
            if hasattr(self, 'max_drawdown') and self.max_drawdown:
                if self.max_drawdown > 0.7:
                    advice_parts.append(f"⚠️ 历史最大回撤高达{self.max_drawdown:.1%}，风险较高")
                elif self.max_drawdown > 0.5:
                    advice_parts.append(f"⚠️ 历史最大回撤{self.max_drawdown:.1%}，需注意风险控制")
                else:
                    advice_parts.append(f"✓ 历史最大回撤{self.max_drawdown:.1%}，风险相对可控")
            
            # 结合回撤频率给出建议
            if hasattr(self, 'drawdowns_per_year') and self.drawdowns_per_year:
                if self.drawdowns_per_year > 8:
                    advice_parts.append("📊 回撤较频繁，建议分批建仓")
                elif self.drawdowns_per_year < 4:
                    advice_parts.append("📈 走势相对稳定，可以考虑长期持有")
            
            return {
                'summary': " ".join(advice_parts),
                'position_advice': position,
                'valuation_score': score
            }
            
        except Exception as e:
            print(f"生成投资建议时发生错误: {str(e)}")
            return "投资建议生成失败，建议咨询专业投资顾问"

    def _display_valuation_and_advice(self):
        """显示估值分析和投资建议"""
        print(f"\n当前估值分析报告:")
        print("=" * 60)
        
        # 基本信息
        if self.current_price:
            print(f"当前价格: ${self.current_price:.2f}")
        
        if self.pe_ratio:
            pe_status = "偏低" if self.pe_ratio < 15 else "偏高" if self.pe_ratio > 25 else "合理"
            print(f"PE比率: {self.pe_ratio:.2f} ({pe_status})")
        
        if self.pb_ratio:
            pb_status = "偏低" if self.pb_ratio < 1.5 else "偏高" if self.pb_ratio > 3 else "合理"
            print(f"PB比率: {self.pb_ratio:.2f} ({pb_status})")
        
        if self.dividend_yield:
            div_status = "优秀" if self.dividend_yield > 3 else "良好" if self.dividend_yield > 1.5 else "一般"
            print(f"股息收益率: {self.dividend_yield:.2f}% ({div_status})")
        
        # 估值评分
        if self.valuation_score is not None:
            score_level = "低估" if self.valuation_score >= 75 else "合理" if self.valuation_score >= 50 else "高估"
            print(f"\n📊 估值评分: {self.valuation_score:.1f}/100 ({score_level})")
        
        # 投资建议
        if self.investment_advice:
            print(f"\n💡 投资建议:")
            if isinstance(self.investment_advice, dict):
                print(f"  {self.investment_advice['summary']}")
                print(f"  仓位建议: {self.investment_advice['position_advice']}")
            else:
                print(f"  {self.investment_advice}")

    def draw_drawdown_chart(self):
        """
        绘制回撤分析图表
        """
        if self.data is None or self.data.empty:
            logging.error("数据不存在或为空，无法绘制回撤图表")
            return

        # 计算回撤数据（如果尚未计算）
        if self.max_drawdown is None:
            self.calculate_max_drawdown()

        # 获取正确的Close列名
        close_col = self._get_close_column_name()
        if close_col is None:
            logging.error("无法找到Close列，无法绘制回撤图表")
            return

        plt.rcParams['font.family'] = ['SimHei']

        fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 10))

        # 子图1: 价格走势和最大回撤标注
        ax1.plot(self.data.index, self.data[close_col], label=f'{self.code} 价格', linewidth=1)

        # 标注最大回撤区间
        if self.max_drawdown_start and self.max_drawdown_end:
            mask = (self.data.index >= self.max_drawdown_start) & (self.data.index <= self.max_drawdown_end)
            ax1.fill_between(self.data.index[mask],
                             self.data[close_col][mask],
                             self.data[close_col].loc[self.max_drawdown_start],
                             alpha=0.3, color='red',
                             label=f'最大回撤: {self.max_drawdown:.2%}')

            ax1.axvline(self.max_drawdown_start, color='green', linestyle='--', alpha=0.7, label='回撤开始')
            ax1.axvline(self.max_drawdown_end, color='red', linestyle='--', alpha=0.7, label='回撤结束')

        ax1.set_title(f'{self.code} 价格走势与最大回撤', fontsize=14)
        ax1.set_ylabel('价格')
        ax1.legend()
        ax1.grid(True, alpha=0.3)

        # 子图2: 滚动最大回撤
        if hasattr(self, 'multi_period_drawdowns') and self.multi_period_drawdowns:
            # 选择一年期回撤数据进行展示
            if '一年期(252天)' in self.multi_period_drawdowns:
                one_year_dd = self.multi_period_drawdowns['一年期(252天)']
                ax2.plot(one_year_dd.index,
                         one_year_dd.values * 100,
                         color='darkred', linewidth=1, label='一年期滚动最大回撤')
                ax2.fill_between(one_year_dd.index,
                                 one_year_dd.values * 100,
                                 alpha=0.3, color='red')
            
            ax2.set_title('一年期滚动最大回撤', fontsize=14)
            ax2.set_ylabel('最大回撤 (%)')
            ax2.set_xlabel('日期')
            ax2.grid(True, alpha=0.3)
            ax2.legend()

        plt.tight_layout()
        plt.show()


if __name__ == "__main__":
    """主程序入口 - 股票分析程序（仅最大回撤和估值分析）"""
    try:
        logger.info("🚀 启动股票分析程序")
        logger.info("=" * 60)
        
        # 定义分析对象
        analysis_targets = {
            '纳斯达克100': '^NDX',
            '上证指数': '000001.SS', 
            '沪深300': '000300.SS',
            '红利低波': '930955.SS'
        }
        
        # 设置您需要的时间范围
        start_date = '2010-10-01'  # 修改为与现有JSON数据匹配的时间
        end_date = None
        
        # 设置分析目标
        target_name = '纳斯达克100'
        code = analysis_targets[target_name]
        
        logger.info(f"📊 分析目标: {target_name} ({code})")
        logger.info(f"📅 时间范围: {start_date} - {'至今' if end_date is None else end_date}")
        
        # 指定数据目录
        data_directory = os.path.join(os.getcwd(), 'stock_data')
        
        # 创建分析实例
        logger.info("🔧 初始化分析实例...")
        stock_analysis = StockAnalysis(code, start_date, end_date, data_dir=data_directory)
        
        # 执行数据获取（优化版本：根据start_date智能过滤）
        logger.info("📥 开始获取数据...")
        stock_analysis.get_data()
        
        if stock_analysis.data is not None:
            logger.info("✅ 数据获取成功")
            
            # 创建markdown输出管理器
            markdown_file = os.path.join(stock_analysis.output_manager.output_dir, 
                                       f"{target_name}_分析报告_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md")
            
            # 写入markdown文件头部
            with open(markdown_file, 'w', encoding='utf-8') as f:
                f.write(f"# {target_name} ({code}) 分析报告\n\n")
                f.write(f"**分析时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
                f.write(f"**数据时间范围**: {stock_analysis.data.index[0].strftime('%Y-%m-%d')} - {stock_analysis.data.index[-1].strftime('%Y-%m-%d')}\n\n")
                f.write(f"**数据源**: {code}\n\n")
                f.write(f"**总记录数**: {len(stock_analysis.data):,} 条\n\n")
                f.write("---\n\n")
            
            # 1. 最大回撤分析
            logger.info("📉 执行最大回撤分析...")
            stock_analysis.analyze_drawdown()
            
            # 将最大回撤分析结果保存到markdown
            with open(markdown_file, 'a', encoding='utf-8') as f:
                f.write("## 📉 最大回撤分析\n\n")
                if hasattr(stock_analysis, 'max_drawdown') and stock_analysis.max_drawdown is not None:
                    f.write(f"**最大回撤**: {stock_analysis.max_drawdown:.2%}\n\n")
                    if stock_analysis.max_drawdown_start and stock_analysis.max_drawdown_end:
                        f.write(f"**回撤开始时间**: {stock_analysis.max_drawdown_start.strftime('%Y-%m-%d')}\n\n")
                        f.write(f"**回撤结束时间**: {stock_analysis.max_drawdown_end.strftime('%Y-%m-%d')}\n\n")
                        f.write(f"**回撤持续天数**: {(stock_analysis.max_drawdown_end - stock_analysis.max_drawdown_start).days} 天\n\n")
                
                # 如果有详细的回撤统计信息，也写入markdown
                if hasattr(stock_analysis, 'multi_period_drawdowns') and stock_analysis.multi_period_drawdowns:
                    f.write("### 📊 多周期回撤分析\n\n")
                    for period, drawdown_data in stock_analysis.multi_period_drawdowns.items():
                        current_dd = drawdown_data.iloc[-1] if not drawdown_data.empty else 0
                        f.write(f"- **{period}**: {current_dd:.2%}\n")
                    f.write("\n")
                f.write("---\n\n")
            
            # 2. 估值分析
            logger.info("💰 执行估值分析...")
            stock_analysis._display_valuation_and_advice()

            # 将估值分析结果保存到markdown
            with open(markdown_file, 'a', encoding='utf-8') as f:
                f.write("## 💰 估值分析\n\n")

                # 获取价格信息用于估值分析
                close_col = stock_analysis._get_close_column_name()
                if close_col:
                    current_price = stock_analysis.data[close_col].iloc[-1]
                    f.write(f"**当前价格**: ${current_price:.2f}\n\n")

                    # PE比率
                    if hasattr(stock_analysis, 'pe_ratio') and stock_analysis.pe_ratio:
                        pe_status = "低估" if stock_analysis.pe_ratio < 15 else "合理" if stock_analysis.pe_ratio < 25 else "高估"
                        f.write(f"**PE比率**: {stock_analysis.pe_ratio:.2f} ({pe_status})\n\n")

                    # PB比率
                    if hasattr(stock_analysis, 'pb_ratio') and stock_analysis.pb_ratio:
                        pb_status = "低估" if stock_analysis.pb_ratio < 1.5 else "合理" if stock_analysis.pb_ratio < 3 else "高估"
                        f.write(f"**PB比率**: {stock_analysis.pb_ratio:.2f} ({pb_status})\n\n")

                    # 股息收益率
                    if hasattr(stock_analysis, 'dividend_yield') and stock_analysis.dividend_yield:
                        div_status = "优秀" if stock_analysis.dividend_yield > 3 else "良好" if stock_analysis.dividend_yield > 1.5 else "一般"
                        f.write(f"**股息收益率**: {stock_analysis.dividend_yield:.2f}% ({div_status})\n\n")

                    # 估值评分
                    if hasattr(stock_analysis, 'valuation_score') and stock_analysis.valuation_score is not None:
                        score_level = "低估" if stock_analysis.valuation_score >= 75 else "合理" if stock_analysis.valuation_score >= 50 else "高估"
                        f.write(f"**估值评分**: {stock_analysis.valuation_score:.1f}/100 ({score_level})\n\n")

                # 投资建议
                if hasattr(stock_analysis, 'investment_advice') and stock_analysis.investment_advice:
                    f.write("### 💡 投资建议\n\n")
                    if isinstance(stock_analysis.investment_advice, dict):
                        f.write(f"**总结**: {stock_analysis.investment_advice['summary']}\n\n")
                        f.write(f"**仓位建议**: {stock_analysis.investment_advice['position_advice']}\n\n")
                    else:
                        f.write(f"{stock_analysis.investment_advice}\n\n")

                f.write("---\n\n")
                f.write(f"*报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n")
                f.write(f"*日志文件: {LOG_FILE}*\n")

            logger.info(f"✅ 分析完成！Markdown报告已保存到: {markdown_file}")
            print(f"\n🎉 分析完成!")
            print(f"📄 Markdown报告: {markdown_file}")
            print(f"📊 日志文件: {LOG_FILE}")
            print(f"📁 输出目录: {stock_analysis.output_manager.output_dir}")
            
        else:
            logger.error("❌ 数据获取失败，无法进行分析")
            
    except Exception as e:
        logger.error(f"❌ 程序执行过程中发生错误: {e}")
        print(f"❌ 程序执行失败: {e}")
        raise
    
    finally:
        logger.info("🏁 程序执行完成")
        print("\n🏁 程序执行完成")